#include <sys/socket.h>
#include <stdarg.h>
#include "nstar_adt_httputil.h"
#include "nstar_adt_http_page.h"

extern int http_send(unsigned char *data, unsigned int len);
extern int http_rec(unsigned char *data, unsigned int rmax_len);

#define HTML_PTYPE_HEAD "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length:%d\r\n\r\n"
	
unsigned char http_data_buf[HTTP_SPRINTF_MAXLEN];
volatile unsigned int http_data_len;
static int raw_content_len;
static uint32_t node_idx;
int http_buf_addlen;

void http_sprintf_init(void)
{
	http_data_len=0;
}

void http_sprintf_addhead(void)
{
	http_send(http_data_buf, http_data_len);
}

void http_sprintf_send(void)
{
	unsigned char headbuf[100];
	int hend_len;
	hend_len= sprintf((char*)headbuf, HTML_PTYPE_HEAD, http_data_len);
	http_send(headbuf, hend_len);
	if(http_data_len > 1 && http_data_len < HTTP_SPRINTF_MAXLEN)
		http_send(http_data_buf, http_data_len);
}

static unsigned char GET_comp_uri(const char* uri, const char* str)
{
	unsigned int len= strlen(str);
	unsigned char ret=URI_REPOS_UNVAILD;
	if(len == 0 || uri[0]!='/')
		return ret;
	uri++;
	if(0 == strncmp(uri, str, len)){
		if(0 == strncmp(&uri[len], URI_HTML, strlen(URI_HTML)))
			ret= URI_REPOS_HTML;
		else if(0 == strncmp(&uri[len], URI_JSON, strlen(URI_JSON)))
			ret= URI_REPOS_JSON;
	}
	return ret;
}

static unsigned char _comp_uri(const char* uri, const char* str)
{
	return (0 == strncmp(uri,str,strlen(str)))? 1: 0;
}


static void _repos_method_get(st_http_request     *http_request, unsigned char* http_response)
{
	char *name= http_request->URI;
	unsigned char mode=0;
	if(0 == memcmp(name, "/\0", 2) || _comp_uri(name, "/"HTML_PAGE0_NAME"") ){
		parm0_pos_htm(mode);
		return;
	}

	if((mode= GET_comp_uri(name, HTML_PAGE1_NAME) ) > 0) {
		parm1_pos_htm(mode);
	}
	else if((mode= GET_comp_uri(name, HTML_PAGE2_NAME) ) > 0) {
		parm2_pos_htm(mode);
    }   
    else if((mode= GET_comp_uri(name, HTML_PAGE3_NAME) ) > 0) {
		parm3_pos_htm(mode);
    }
    else if((mode= GET_comp_uri(name, HTML_PAGE4_NAME) ) > 0) {
		parm4_pos_htm(mode);
    }
	else if(_comp_uri(name,"/favicon.ico")){
		/*nothing need to do*/
	}

}

static void _repos_method_post(st_http_request     *http_request, unsigned char* http_response)
{
	char req_name[32]={0x00,};			
	char *uri= http_request->URI;
	http_mid(uri, "/", " ", req_name);
	if(strcmp(req_name,""HTML_PAGE0_NAME".cgi")==0){
		parm0_rpos_cgi(uri);	
		return;
	}
    
    if(strcmp(req_name,""HTML_PAGE1_NAME".cgi") == 0){						  	
		//parm1_rpos_cgi(uri);
	}
	else if(strcmp(req_name,""HTML_PAGE2_NAME".cgi")==0) {						  	
		parm2_rpos_cgi(uri);
	}else if(strcmp(req_name,""HTML_PAGE3_NAME".cgi")==0) {						  	
		parm3_rpos_cgi(uri);
	}else if(strcmp(req_name,""HTML_PAGE4_NAME".cgi")==0) {						  	
		parm4_rpos_cgi(uri);
	}
	else if(strcmp(req_name,""HTML_REBOOT_CGI_NAME".cgi")==0) {			  	
		rpos_reboot_cgi();
	}

}

static void proc_http(void)
{								
	unsigned char* http_response;
	st_http_request *http_request;
	http_response = (unsigned char*)nstar_web_rx_buf;
	http_request = (st_http_request*)nstar_web_tx_buf;
	memset(http_request,0x00,MAX_URI_SIZE);
	parse_http_request(http_request, (unsigned char*)nstar_web_rx_buf);
	switch (http_request->METHOD)	
 	{
		case METHOD_ERR:
			http_send((unsigned char*)ERROR_REQUEST_PAGE, sizeof(ERROR_REQUEST_PAGE));
			break;
		case METHOD_HEAD:			
		case METHOD_GET:	
			_repos_method_get(http_request, http_response);
			break;
		case METHOD_POST:
			_repos_method_post(http_request, http_response);
			break;
		default:
			break;
	}
}

int do_https(void)
{			
	int len;									
	len	= http_rec((unsigned char*)nstar_web_rx_buf, MAX_URI_SIZE);
	if(len < 1)
		return 0;
	nstar_web_rx_buf[len] = 0;
	raw_content_len= len;
	proc_http();	
	return len; 
}

void http_page_htm(const char *name, const char *body, void (fun_add_elemnet)(unsigned char))
{
	http_sprintf_init();
	http_sprintf("%s%s", HTML_PARM_HEAD, body);
	http_sprintf(REQUST_JSCRIPT_HEAD, name);
	fun_add_elemnet(URI_REPOS_HTML);
	REQUST_JSCRIPT_END(name);
	http_sprintf_send();
}

void http_page_json(const char *name, void (fun_add_elemnet)(unsigned char))
{
	http_sprintf_init();
	http_sprintf("json_%s%s", name, JSON_START_SYMBOL);
	fun_add_elemnet(URI_REPOS_JSON);
	http_sprintf(JSON_END_SYMBOL);
	http_sprintf_send();
}

void http_handle_parm(char *p_content, char *name, void(fun_set_parm)(char*))
{
	char *p_parm= get_http_param_value((unsigned char*)nstar_web_rx_buf, p_content, name);		
	if(p_parm)
	{	
		fun_set_parm(p_parm);
	}
}


void _node_start(void) {
    node_idx = 0;
}

void _node_add(const struct js_node *p) {
    char id[12] ;
    snprintf(id, 12, "%s%02d", JSN_NAME, node_idx++);
    if(p->tips == NULL) {
        http_sprintf(HTM_BODY_ELEMENT_STR_0, p->titile, p->text_size, id, id);
    }else {
        http_sprintf(HTM_BODY_ELEMENT_STR_1, p->titile, p->text_size, id, id, p->tips);
    }
}

void _jsreq_add(const struct js_node *p) {
    char str[12] ;
    snprintf(str, 12, "%s%02d", JSN_NAME, node_idx++);
    REQUST_JSCRIPT_ELEMENT(str);
}

void _jsrepos_add(const struct js_node *p) {
    char str[40] ;
    if(p->make_str) {
        p->make_str(str, 40);
    }else {
        uint32_t tmp = 0;
        memcpy((uint8_t*)&tmp, p->pdata, p->dsize);
        sprintf(str, "%u", tmp);
    }
    http_sprintf("'%s%02d':'%s',",JSN_NAME, node_idx++, str);
}

void _node_ack(const struct js_node *p, char *p_content, void (*user_cb)(void)) {
    char id[12], *p_parm = NULL;
    snprintf(id, 12, "%s%02d", JSN_NAME, node_idx++);
    p_parm = get_http_param_value((unsigned char*)nstar_web_rx_buf, p_content, id);		
    if(p_parm) {	
    	if(p->parse_str) {
            p->parse_str(p_parm, 12);
        }else {
            uint32_t val = (uint32_t)atoi(p_parm);
            uint32_t tmp = 0;
            memcpy((uint8_t*)&tmp, p->pdata, p->dsize);
            if(tmp != val) {
                memcpy((uint8_t*)p->pdata, &val, p->dsize);
                user_cb();
            }
        }
    }
}

void list_htm_body(void *plist) {
    uint32_t i = 0;
    const struct js_node *p;
    _node_start();
    while(1) {
        p = (const struct js_node*)plist + i;
        if(p->titile == NULL) {
            break;
        }
        i++;
        _node_add(p);
    }
}

void list_htm_jsreq(void *plist) {
    uint32_t i = 0;
    const struct js_node *p;
    _node_start();
    while(1) {
        p = (const struct js_node*)plist + i;
        if(p->titile == NULL) {
            break;
        }
        i++;
        _jsreq_add(p);
    }
}

void list_htm_jsrepos(void *plist) {
    uint32_t i = 0;
    const struct js_node *p;
    _node_start();
    while(1) {
        p = (const struct js_node*)plist + i;
        if(p->titile == NULL) {
            break;
        }
        i++;
        _jsrepos_add(p);
    }
}

void list_htm_ack(void *plist, char *p_content, void (*user_cb)(void)) {
    uint32_t i = 0;
    const struct js_node *p;
    _node_start();
    while(1) {
        p = (const struct js_node*)plist + i;
        if(p->titile == NULL) {
            break;
        }
        i++;
        _node_ack(p, p_content, user_cb);
    }
}


